|
mruby 4.0.0
mruby is the lightweight implementation of the Ruby language
|
In mruby, you can customize how memory is allocated in two ways:
malloc()/realloc()/free()mrb_basic_alloc_func()malloc()/realloc()/free()On platforms without a full C standard library —such as many microcontrollers— you may need to supply your own implementations of malloc(), realloc(), and free(). mruby’s allocator calls directly into these functions, so replacing them lets you control every allocation and deallocation performed by your entire program, including any third‑party libraries you link against.
Keep in mind:
realloc(NULL, size) must behave like malloc(size).free(NULL) must be a no‑op.Simply define these three functions in your code (or link against a library that provides them), and mruby — along with all other code in your process — will use your versions automatically.
mrb_basic_alloc_func()Inside mruby, all of its own memory allocations go through a single function called mrb_basic_alloc_func() (formerly mrb_default_allocf()). By defining this function in your application before linking, you can intercept and handle only the memory operations initiated by mruby itself without affecting other libraries or parts of your program.
Implement mrb_basic_alloc_func() in your code, and mruby will invoke it for every internal allocation, reallocation, and free request.
mrb_basic_alloc_func(NULL, size) should allocate size bytes, just like malloc(size).mrb_basic_alloc_func(ptr, size) should resize the existing block at ptr to size bytes, just like realloc(ptr, size).mrb_basic_alloc_func(ptr, 0) should free the block at ptr, just like free(ptr).malloc/realloc/free: replaces allocation behavior globally (mruby + all other code and third‑party libraries).mrb_basic_alloc_func(): replaces allocation behavior only for mruby’s internal use, leaving other libraries’ allocations untouched.If you are moving from the old API:
mrb_open_allocf()_Old:
_New:
c // No allocf parameter; set up your hook via mrb_basic_alloc_func definition. mrb_state *mrb = mrb_open_core();
mrb_open_core() takes no argumentsmrb_basic_alloc_func as you need.mrb_allocf typeDefinitions using the mrb_allocf typedef can be removed; implement mrb_basic_alloc_func() with the signature below:
mrb_basic_alloc_func signature changeOld:
New:
c void* mrb_basic_alloc_func(void *ptr, size_t size);
Old style:
New style:
By default, mruby allocates GC heap pages individually via malloc(). On embedded targets with multiple memory banks (e.g., STM32 CCM+SRAM, ESP32 PSRAM+IRAM), you may want to place heap pages in a specific memory region. mrb_gc_add_region() lets you provide a contiguous buffer that mruby carves into heap pages.
start: pointer to a contiguous memory buffer.size: size of the buffer in bytes.The buffer is aligned internally to pointer size. Each page is approximately 40 KB on 64-bit systems (24 KB on 32-bit). The caller retains ownership of the buffer and must keep it valid for the lifetime of the mrb_state.
When mrb_gc_add_region() is called, mruby:
mrb_heap_page-sized chunks.Region pages participate in the normal GC cycle (mark-and-sweep) like any other heap page. The only differences are:
free() on region pages, even if all objects on a page are dead. The page stays in the heap with an empty freelist, ready for reuse.malloc() for new pages as usual.mrb_close() frees the internal region descriptor but does not free the buffer itself.The page size is controlled by MRB_HEAP_PAGE_SIZE (default: 1024 slots). Each page occupies:
| Platform | Slot size | Page size (approx) |
|---|---|---|
| 64-bit | 40 bytes | ~41 KB |
| 32-bit | 24 bytes | ~25 KB |
To estimate pages for a given buffer: pages = buffer_size / sizeof(mrb_heap_page). Each page provides MRB_HEAP_PAGE_SIZE object slots.